--------------------------------------------------
-- Level code
-- Created 4:14 2019-8-27
--------------------------------------------------

SaveData["episode"] = SaveData["episode"] or {}


--[[ TODO:
	- Shop ideas:
		- [x] Costume changer
			- [x] Buy it once, change the costumes of any character at any time
		- [x] Character changer
			- Next upgrade that can be bought after already buying Costume Changer, takes it's place.
		- [ ] Instant character changer
			- Upgrade after the last
			- On-the-fly character changing at the push of a button (combination)
				- Make sure it's compatible with controllers!
				- Have it be Down+Alt-Jump?
		- [ ] Half Price at the Shops
			- Does what it says on the tin.
]]

local AmntOfStarCoins

require("Libraries.nsmbwalls")

local function ChangeLayers()
	-- [[ Life Saver ]] --
	local LSaverBlock = Layer.get("Pre-Purchase Live Saver")
	local LSaverNoMore = Layer.get("Life Saver Bought")
	if globalsave.LifeSaver then
		LSaverBlock:hide(true)
		LSaverNoMore:show(true)
	else
		LSaverBlock:show(true)
		LSaverNoMore:hide(true)
	end

	-- [[ Costume Changer ]] --
	local CChangerBlock = Layer.get("Pre-Purchase Costume Changer")
	local CChanger = Layer.get("Costume Changer")
	if globalsave.CostumeChanger then
		CChangerBlock:hide(false)
		CChanger:show(false)
	else
		CChangerBlock:show(false)
		CChanger:hide(false)
	end


	-- [[ Character Door ]] --
	local CharacterDoorBlock = Layer.get("Pre-Purchase Character Door")
	local CharacterDoorLayer = Layer.get("Character Door")
	if globalsave.CharacterDoor then
		CharacterDoorBlock:hide(false)
		CharacterDoorLayer:show(false)
	elseif globalsave.CostumeChanger then
		CharacterDoorBlock:show(false)
		CharacterDoorLayer:hide(false)
	else
		CharacterDoorBlock:hide(false)
		CharacterDoorLayer:hide(false)
	end	

	-- [[ Second Item Slot ]] --
	local SecondItemBlock = Layer.get("Pre-Purchase Second Item Slot")
	if globalsave.SecondItemSlot then
		SecondItemBlock:hide(false)
	elseif (globalsave.CharacterDoor and globalsave.CostumeChanger) then
		SecondItemBlock:show(false)
	else
		SecondItemBlock:hide(false)
	end	

	-- [[ Hard Mode Purchase ]] --
	local HardModeBlock = Layer.get("Hard Mode Purchase")
	if globalsave.HardModePurchase then
		HardModeBlock:hide(false)
	elseif (globalsave.CostumeChanger) then
		HardModeBlock:show(false)
	else
		HardModeBlock:hide(false)
	end
end

function onStart()
	if not globalsave.StarCoinsSpent then
		globalsave.StarCoinsSpent = 0
	end
	Misc.saveGame()
	AmntOfStarCoins = SaveData._basegame.starcoinCounter - globalsave.StarCoinsSpent

	-- -- [[Layers]]  -- --

	local LockingSign = Layer.get("The Locking Sign")
	local LockedDoors = Layer.get("The Doors That Were Once Locked")

	local ToadMan = Layer.get("Todd And His Friend")
	local BridgeMan = Layer.get("Burnt Bridge")

	local BridgeLand = Layer.get("The BridgeLand")

	local TrashLayer = Layer.get("Trash Layer")

	local CatMario = Layer.get("Cat")

	local Unfound2Layer = Layer.get("finder 2")

	local pranklayer = Layer.get("The Pranker")
	local prank2layer = Layer.get("Got Pranked")
	local prank3layer = Layer.get("Pre Prank")
	
	local town2layer = Layer.get("A Populated Town")
	
	-- -- [[Save Code]] -- --

	if globalsave.ChangedChar then
		player.character = globalsave.ChangedChar
	end

    if globalsave.DefeatBirdo then -- Opens doors if Fire Birdo is defeated.
		ToadMan:hide(true)
		BridgeMan:show(true)
		BridgeLand:show(true)
	else
		ToadMan:show(true)
		BridgeMan:hide(true)
		BridgeLand:hide(true)
	end

	if globalsave.SaveTheTown then -- player has defeated boom boom in world 2
		town2layer:show(true)
	else
		town2layer:hide(true)
		triggerEvent("Silence Town 2")
	end

	if globalsave.OpenCastle then
		LockingSign:hide(true)
		LockedDoors:show(true)
	else
		LockedDoors:hide(true)
		LockingSign:show(true)
	end

	if globalsave.FixElevator then
		triggerEvent("FixElevator")
	end

	if globalsave.CompleteSML then
		triggerEvent("BitchSwitch")
	end

	if globalsave.RunElevatorUp then
		triggerEvent("RunItUpOnce")
		globalsave.RunElevatorUp = false
	end
	
	if globalsave.unfounded then
		triggerEvent("unfound silent")
	else
		Unfound2Layer:hide(true)
	end
	
	if globalsave.unfounded2 then
		triggerEvent("unfound2 silent")
	end

	if globalsave.Cat then -- cat mario switch found
		CatMario:show(true)
	else
		CatMario:hide(true)
	end

	--[[if globalsave.BridgeLand then -- Access to second world granted
		BridgeLand:show(true)
	else
		BridgeLand:hide(true)
	end]]

	if globalsave.Pranked then -- happens when entering ice level for first time
		pranklayer:hide(true)
		prank2layer:show(true)
		prank3layer:hide(true)
	else
		prank2layer:hide(true)
		if tonumber(mem(0x00B251E0,FIELD_WORD)) < 3 then -- less than three stars, toad doesn't need help yet
			pranklayer:hide(true)
			prank3layer:show(true)
		else
			pranklayer:show(true)
			prank3layer:hide(true)
		end
	end

	if globalsave.GarbageDay then -- Misc.doBombExplosion
		TrashLayer:hide(true)
	else
		TrashLayer:show(true)
	end
end

local CDChangeBlock = false
local BlockPlaced1 = nil
local BlockPlaced2 = nil

-- Run code every frame (~1/65 second)
-- (code will be executed before game logic will be processed)
function onTick()
	AmntOfStarCoins = SaveData._basegame.starcoinCounter - globalsave.StarCoinsSpent
	-- [[ Costume Changing ]] --
	for _,plyr in ipairs(Player.get()) do
		if globalsave.CostumeChanger then
			if not gplayerData[plyr.idx].InDoor and plyr.forcedState == FORCEDSTATE_DOOR and (tonumber(plyr:mem(0x15E,FIELD_WORD)) == 28 or tonumber(plyr:mem(0x15E,FIELD_WORD)) == 29 or tonumber(plyr:mem(0x15E,FIELD_WORD)) == 30 or tonumber(plyr:mem(0x15E,FIELD_WORD)) == 31) then
				gplayerData[plyr.idx].InDoor = true
				if tonumber(plyr:mem(0x15E,FIELD_WORD)) == 30 or tonumber(plyr:mem(0x15E,FIELD_WORD)) == 31 then
					gplayerData[plyr.idx].CharacterSwapNow = true
				else
					gplayerData[plyr.idx].CharacterSwapNow = false
				end
			end
			

			if gplayerData[plyr.idx].InDoor and plyr.forcedState ~= FORCEDSTATE_DOOR then
				gplayerData[plyr.idx].InDoor = false
				if not gplayerData[plyr.idx].CharacterSwapNow then
					if plyr.character == CHARACTER_MARIO then
						if plyr.getCostume(plyr.character) == "SMW-MARIO" then
							plyr.setCostume(plyr.character, nil, false)
						else
							plyr.setCostume(plyr.character, "SMW-MARIO", false)
						end
					elseif plyr.character == CHARACTER_LUIGI then
						if plyr.getCostume(plyr.character) == "SMW-LUIGI" then
							plyr.setCostume(plyr.character, nil, false)
						else
							plyr.setCostume(plyr.character, "SMW-LUIGI", false)
						end
					elseif plyr.character == CHARACTER_PEACH then
						if plyr.getCostume(plyr.character) == "SMB3-PEACH" then
							plyr.setCostume(plyr.character, nil, false)
						else
							plyr.setCostume(plyr.character, "SMB3-PEACH", false)
						end
					end
				elseif gplayerData[plyr.idx].CharacterSwapNow then
					if plyr.character == CHARACTER_MARIO then
						plyr.character = CHARACTER_LUIGI
					elseif plyr.character == CHARACTER_LUIGI then
						plyr.character = CHARACTER_PEACH
					elseif plyr.character == CHARACTER_PEACH then
						plyr.character = CHARACTER_TOAD
					elseif plyr.character == CHARACTER_TOAD then
						plyr.character = CHARACTER_MARIO
					end
					globalsave.ChangedChar = plyr.character
					gplayerData[plyr.idx].CharacterSwapNow = false
					CDChangeBlock = true
				end
			end
		end
	end

	-- [[ Block under character door ]] --
	if globalsave.CharacterDoor then
		if CDChangeBlock then
			if BlockPlaced1 then
				BlockPlaced1:delete()
				BlockPlaced1 = nil
			end
			if BlockPlaced2 then
				BlockPlaced2:delete()
				BlockPlaced2 = nil
			end
			CDChangeBlock = false
		end
		if not BlockPlaced1 then
			local BlockTime = 622
			if player.character == CHARACTER_MARIO then
				BlockTime = 623
			elseif player.character == CHARACTER_LUIGI then
				BlockTime = 624
			elseif player.character == CHARACTER_PEACH then
				BlockTime = 625
			elseif player.character == CHARACTER_TOAD then
				BlockTime = 622
			end
			BlockPlaced1 = Block.spawn(BlockTime, -99392, -100288)
			BlockPlaced2 = Block.spawn(BlockTime, -79328, -80288)
		end
	else
		if BlockPlaced1 then
			BlockPlaced1:delete()
			BlockPlaced1 = nil
		end
		if BlockPlaced2 then
			BlockPlaced2:delete()
			BlockPlaced2 = nil
		end
	end
	
	-- [ Revert Character Door if no Costume Changer ] --
	-- mainly just for debugging purposes
	if globalsave.CharacterDoor and not globalsave.CostumeChanger then
		globalsave.CharacterDoor = false
	end
	if globalsave.SecondItemSlot and not globalsave.CharacterDoor then
		globalsave.SecondItemSlot = false
	end
end

local function GiveTheItem(npcid, money, sfx, starcoin, forcesection)
	if not forcesection or (forcesection == 21 or forcesection == 0) then
		forcesection = player.section
	end
	if (not starcoin and myCurrency._value >= money) 
	or (starcoin and AmntOfStarCoins >= money) then
		local XPos = -100000
		local YPos = -100064
		if forcesection == 6 then
			XPos = -79936
			YPos = -80064
		end
		if tonumber(npcid) then
			local Item = NPC.spawn(npcid, XPos+16, YPos, forcesection)
			Effect.spawn(10, Item.x + Item.width*0.5 - 16, Item.y + Item.height*0.5 -16)
			Item.speedY = -10
			Item.dontMove = true
		elseif type(npcid) == "string" then
			if not globalsave[npcid] then
				globalsave[npcid] = true
			else -- this shouldn't happen, but just in case...
				SFX.play(39)
				return false
			end
		end
		if not starcoin then
			changemoney(-money)
			if money > math.abs(0) then
				coinFX.AddCoin(math.ceil(money/10))
			end
		else
			globalsave.StarCoinsSpent = globalsave.StarCoinsSpent + money
			coinFX.AddCoin(money, "GFX/starcoin", 3, 20, 106)
		end
		if tonumber(sfx) then
			SFX.play(sfx)
		elseif type(sfx) == "string" then
			local transsfx = Misc.resolveFile(sfx)
			Audio.playSFX(sfx)
		end
		return true
	else
		SFX.play(39)
		return false
	end
end

local function FunnyShopBox(eventName, wtfdoido)
	if eventName == "Mushroom" then
		GiveTheItem(9, 10, 7, false, wtfdoido)
	elseif eventName == "Fire Flower" then
		GiveTheItem(14, 20, 7, false, wtfdoido)
	elseif eventName == "Ice Flower" then
		GiveTheItem(264, 30, 7, false, wtfdoido)
	elseif eventName == "Life Saver Purchase" then
		GiveTheItem("LifeSaver", 200, 12, false, wtfdoido)
	elseif eventName == "Costume Changer Purchase" then
		GiveTheItem("CostumeChanger", 3, 41, true)
	elseif eventName == "Character Door Purchase" then
		GiveTheItem("CharacterDoor", 6, 41, true)
	elseif eventName == "Second Item Slot Purchase" then
		GiveTheItem("SecondItemSlot", 9, 41, true)
	elseif eventName == "Hard Mode Purchase" then
		GiveTheItem("HardModePurchase", 50, 32)
	end
end


function onEvent(eventName)
	local wtfdoido = 0
	if player2 ~= nil then
		if (player.section == 5 or player.section == 6) and (player2.section == 5 or player2.section == 6) then
			wtfdoido = 21 -- force spawn in both sections
		elseif (player.section ~= 5 and player.section ~= 6) and (player2.section == 5 or player2.section == 6) then
			wtfdoido = player2.section -- force spawn in player2's section
		end
	end

	FunnyShopBox(eventName, wtfdoido)
	if wtfdoido == 21 then
		FunnyShopBox(eventName, player2.section)
	end

	if eventName == "unfound" then
		globalsave.unfounded = true
	end	
	if eventName == "unfound2" then
		globalsave.unfounded2 = true
	end

	if eventName == "Points2Coins" then
		if SaveData._basegame.hud.score - 10000 > 0 then
			SaveData._basegame.hud.score = SaveData._basegame.hud.score - 10000
			changemoney(10, true)
			coinFX.AddCoin(2)
		else
			SFX.play(39)
		end
	end

	ChangeLayers()
end

local function AddPrice(origx, origy, text, starcoin)
	local CoinGFX
	if starcoin then
		CoinGFX = "🌟 "
	elseif tonumber(text) then
		CoinGFX = "💵 "
	else
		CoinGFX = ""
	end
	function PrintThing(x, y)
		textplus.print{
			sceneCoords = true,
			x = x + 7,
			y = y,
			pivot = {0.5, 0.5},
			text = "<size 2> " .. CoinGFX .. tostring(text) .. "</size>",
			font = GoodFont2
		}
	end
	PrintThing(origx, origy)
	PrintThing(origx + 20064, origy + 20000)
end

function onDraw()
	AddPrice(-99856, -100176, 10) -- mushroom
	AddPrice(-99728, -100176, 20) -- fire flower
	AddPrice(-99600, -100176, 30) -- ice flower

	if not globalsave.CostumeChanger then
		AddPrice(-99856, -100176-256, 3, true) -- costume changer
	elseif not globalsave.CharacterDoor then
		AddPrice(-99856, -100176-256, 6, true) -- character door
	elseif not globalsave.SecondItemSlot then
		AddPrice(-99856, -100176-256, 9, true) -- second item slot
	end
	AddPrice(-99728, -100176-256, 200) -- life saver
	
	if not globalsave.HardModePurchase and globalsave.CostumeChanger then
		AddPrice(-99600, -100176-256, 50) -- hard mode
	end
end